package com.vcms.controller.storemanagement;

// Copyright 1997 ISS.
// The contents contained in this document may not be reproduced in any
// form or by any means, without the written permission of ISS, other
// than for the purpose for which it has been supplied.
//
// Author: Olivo Miotto
//

import com.vcms.controller.maintenance.MaintenanceController;
import com.vcms.controller.system.MainController;
import com.vcms.entity.store.CashStore;
import com.vcms.entity.store.DrinksStore;
import com.vcms.entity.store.Store;
import com.vcms.entity.store.item.CashStoreItem;
import com.vcms.entity.store.item.DrinksStoreItem;
import com.vcms.entity.store.item.StoreItem;
import com.vcms.entity.store.itemtype.Coin;
import com.vcms.entity.store.itemtype.DrinksBrand;
import com.vcms.entity.store.itemtype.StoreObject;
import com.vcms.exception.VMCSException;
import com.vcms.utility.loader.storage.CashStorageLoader;
import com.vcms.utility.loader.storage.DrinkStorageLoader;

public class StoreController {
	public final static char CASH = 'C';
	public final static char DRINK = 'D';

	private CashStore cashStore;
	private DrinksStore drinkStore;
//	private CashPropertyLoader cashPropertyLoader;
//	private DrinkPropertyLoader drinkPropertyLoader;
	
	private CashStorageLoader cashStorageLoader;
	private DrinkStorageLoader drinkStorageLoader;

	
	public MainController mainCtrl;

	public StoreController(MainController mctrl) {
		mainCtrl = mctrl;
	}

	public void initialize() throws VMCSException {
		try {
			cashStore = new CashStore();
			drinkStore = new DrinksStore();
			initializeStores();
		} catch (VMCSException e) {
			throw new VMCSException("StoreController.initialize","Error in initialize store controller" + e);
		}
	}

	public void initializeStores() throws VMCSException {
		try {
			initializeCashStore();
			initializeDrinkStore();
		} catch (VMCSException e) {
			e.printStackTrace();
			throw new VMCSException("StoreController.initializeStores",	"Error in initialize cash store" + e);
		}
	}

	public void initializeDrinkStore() throws VMCSException {
		try {
			// get the drink file from the environment property file;
			this.drinkStorageLoader = new DrinkStorageLoader();
			int itemCount = this.drinkStorageLoader.getItemCount();
			this.drinkStore.setStoreSize(itemCount);
			for(int i = 0; i < itemCount; i++){
				this.drinkStore.addItem(i, this.drinkStorageLoader.getItem(i+1 ));
			}
			/* TODO :: need to rectify why there is another function add drinks item?
			 * 
			dsada
			
			drinkPropertyLoader = new DrinkPropertyLoader(Environment.getDrinkPropFile());
			drinkPropertyLoader.initialize();
			int numOfItems =  drinkPropertyLoader.getNumOfItems();
			drinkStore.setStoreSize(numOfItems);
			int i;
			DrinksStoreItem sItem;

			for (i = 0; i < numOfItems; i++) {
				sItem = drinkPropertyLoader.getItem(i + 1);

				// add drink item in this function;
				addDrinksItem(i, sItem);
			}*/

		} catch (Exception e) {
			throw new VMCSException("StoreController.initializeDrinkStore",	"Error in initialize drink store " + e);
		}
	}

	public void initializeCashStore() throws VMCSException {
		try {
			// get the cash file from the environment property file;
			this.cashStorageLoader = new CashStorageLoader();
			int itemCount = this.cashStorageLoader.getItemCount();
			this.cashStore.setStoreSize(itemCount);
			for(int i = 0; i < itemCount; i++){
				cashStore.addItem(i, this.cashStorageLoader.getItem(i+1 ));
			}
			
			
			/*CashPropertyLoader prop = new CashPropertyLoader(Environment.getCashPropFile());
			cashPropertyLoader = prop;
			prop.initialize();
			int numOfItems;

			numOfItems = prop.getNumOfItems();
			cashStore.setStoreSize(numOfItems);
			int i;
			CashStoreItem sItem;

			for (i = 0; i < numOfItems; i++) {
				sItem = prop.getItem(i + 1);

				// add cash item in this function;
				cashStore.addItem(i, (StoreItem) sItem);
			}*/
		} catch (Exception e) {
			e.printStackTrace();
			throw new VMCSException("StoreController.initializeCashStore","Error in initialize cash store " + e);
		}
	}

	public void addDrinksItem(int idx, DrinksStoreItem item)
			throws VMCSException {
		StoreObject ob; // existed object
		StoreObject ob1; // the new object

		ob1 = item.getContent();
		ob = drinkStore.findObject(ob1.getName());

		// check for the consistency of brand price;
		if (ob != null) {
			DrinksBrand bd;
			DrinksBrand bd1;
			bd = (DrinksBrand) ob;
			bd1 = (DrinksBrand) ob1;
			if (bd.getPrice() != bd1.getPrice()) {
				// the new price is not the same as that of the prievous item
				// with the same name;
				throw new VMCSException("StoreController.addDrinksItem",
						"Inconsist brand price");
			}
		}
		if (ob == null) {
			drinkStore.addItem(idx, (StoreItem) item);
			return;
		}
		item.setContent(ob);
		drinkStore.addItem(idx, item);
	}

	

	public int getStoreSize(char type) {
		if (type == StoreController.CASH)
			return cashStore.getStoreSize();
		else
			return drinkStore.getStoreSize();
	}

	public StoreItem[] getStoreItems(char type) {
		if (type == StoreController.CASH)
			return cashStore.getItems();
		else
			return drinkStore.getItems();
	}

	public void changeStoreQty(char type, int idx, int qty) {
		try {
			System.out.println("StoreController.changeStoreQty: type:" + type + "   qty:" + qty);
			
			if (type == StoreController.CASH)
				cashStore.setQuantity(idx, qty);
			else
				drinkStore.setQuantity(idx, qty);
			
			// to automatically change the displayed stock quantitiy.
			// not required in the requirement.
			MaintenanceController mctrl;
			mctrl = mainCtrl.getMaintenanceController();
			mctrl.changeStoreQty(type, idx, qty);

		} catch (VMCSException e) {
			System.out.println("StoreController.changeStoreQty:" + e);
		}
	}

	public StoreItem getStoreItem(char type, int idx) throws VMCSException {
		return (type == StoreController.CASH) ? cashStore.getStoreItem(idx) : drinkStore.getStoreItem(idx);
	}

	public void setPrice(int idx, int pr) throws VMCSException {
		DrinksStoreItem item = (DrinksStoreItem) drinkStore.getStoreItem(idx);
		DrinksBrand bd = (DrinksBrand) item.getContent();
		bd.setPrice(pr);
	}

	public int getTotalCash() throws VMCSException {
		int i;
		int size = cashStore.getStoreSize();
		CashStoreItem item;
		int qty;
		int val;
		int totalCash = 0;
		Coin coin;

		for (i = 0; i < size; i++) {
			item = (CashStoreItem) cashStore.getStoreItem(i);
			qty = item.getQuantity();
			coin = (Coin) item.getContent();
			val = coin.getValue();
			totalCash = totalCash + qty * val;
		}
		return totalCash;
	}

	public int transferAll() throws VMCSException {
		int i;
		int cc = 0; // coin quauntity;
		int size = cashStore.getStoreSize();
		CashStoreItem item;
		for (i = 0; i < size; i++) {
			item = (CashStoreItem) cashStore.getStoreItem(i);
			cc = cc + item.getQuantity();
			item.setQuantity(0);
		}
		return cc;
	}


	public void saveCashProperty() throws VMCSException {
		int size = cashStore.getStoreSize();
		this.cashStorageLoader.setItemCount(size);
		for(int i = 0; i < size; i++){
			this.cashStorageLoader.setItem(i+1, (CashStoreItem) this.cashStore.getStoreItem(i));
		}
		this.cashStorageLoader.flush();
	}

	/**
	 * save the drink property when simulation is ended.
	 */
	public void saveDrinksProperty() throws VMCSException {
		int size = drinkStore.getStoreSize();
		this.drinkStorageLoader.setItemCount(size);
		for(int i=0; i < size; i++){
			this.drinkStorageLoader.setItem(i+1, (DrinksStoreItem)drinkStore.getStoreItem(i));
		}
		this.drinkStorageLoader.flush();
	}
	
	public void dispenseDrink(int idx)  {
		try{
			DrinksStoreItem item = (DrinksStoreItem) this.getStoreItem(StoreController.DRINK,idx);
			item.decrement(idx);
			item.getQuantity();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	
	public void storeCoin(Coin c) {
		try {
			int idx = cashStore.findCashStoreIndex(c);
			CashStoreItem item = (CashStoreItem) this.getStoreItem(StoreController.CASH, idx);
			item.increment();
		} catch (VMCSException e) {
			e.printStackTrace();
		}
		
	}
	
	public boolean giveChange(int coinIndex, int numberOfCoin){
		try{
			CashStoreItem cashStoreItem = (CashStoreItem)this.cashStore.getStoreItem(coinIndex);
			for(int i = 0; i < numberOfCoin; i++){
				cashStoreItem.decrement(coinIndex);
			}
		}catch(Exception e){
			e.printStackTrace();
			return false;
		}
		return true;
	}
	
	
	public void closeDown() throws VMCSException {
		saveCashProperty();
		saveDrinksProperty();
	}

	public Store getStore(char type) {
		if (type == StoreController.CASH)
			return (Store) cashStore;
		else
			return (Store) drinkStore;
	}
	
	public MainController getMainController() {return mainCtrl;}

}
